//
//  DrawingBoardViewController.m
//  TestPrj
//
//  Created by 朱铅峰 on 2019/11/1.
//  Copyright © 2019 Xing. All rights reserved.
//

#import "DrawingBoardViewController.h"
#import <Masonry.h>
#import "DrawingBoardView.h"
#import <Toast/UIView+Toast.h>
#import <AVFoundation/AVFoundation.h>
#import <AVKit/AVKit.h>
#import <Photos/Photos.h>

//视频路径
#define DOCSFOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/"]
#define VideoPath [DOCSFOLDER stringByAppendingPathComponent:@"drawing.mov"]

@interface DrawingBoardViewController ()

@property(nonatomic,strong)DrawingBoardView *boardView;
@property(nonatomic,strong)UIButton *clearBtn;
@property(nonatomic,strong)UIButton *genButton;
@property(nonatomic,strong)NSMutableArray *imagesArray;
@property(nonatomic,assign)long seed;

@end

@implementation DrawingBoardViewController

- (NSMutableArray *)imagesArray {
    
    if (!_imagesArray) {
        _imagesArray = [NSMutableArray array];
    }
    return _imagesArray;
}

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    self.title = @"画板（图片转视频）";
    
    __weak typeof(self) weakSelf = self;
    
    UIView *containerView = [[UIView alloc] init];
    containerView.layer.borderColor = [UIColor blackColor].CGColor;
    containerView.layer.borderWidth = 1;
    [self.view addSubview:containerView];
    
    //    ///对于工程兼容是iOS8开始的(因为safe area是iOS9开始支持的)
    //    ///安全区顶部
    //    make.top.equalTo(self.mas_topLayoutGuide).offset(8);
    //    ///安全区底部
    //    make.top.equalTo(self.mas_bottomLayoutGuide).offset(-8);
    //    ///对于工程支持是iOS11使用
    //    @property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideTop NS_AVAILABLE_IOS(11.0);
    [containerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(@15);
        make.right.equalTo(@-15);
        make.top.equalTo(self.mas_topLayoutGuide).offset(15);
        make.bottom.equalTo(self.mas_bottomLayoutGuide).offset(-60);
    }];
    
    _boardView = [[DrawingBoardView alloc] init];
    _boardView.backgroundColor = [UIColor whiteColor];
    _boardView.drawPathChangeAction = ^(DrawingBezierPath *path) {
        [weakSelf drawPathChangeAction];
    };
    [containerView addSubview:_boardView];
    
    [_boardView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(UIEdgeInsetsZero);
    }];
    
    _clearBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [_clearBtn setTitle:@"清空画板" forState:UIControlStateNormal];
    [_clearBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [_clearBtn addTarget:self action:@selector(clearAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_clearBtn];
    
    _genButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [_genButton setTitle:@"生成并播放" forState:UIControlStateNormal];
    [_genButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [_genButton addTarget:self action:@selector(genVideoAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_genButton];
    
    [_clearBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(50);
        make.top.equalTo(containerView.mas_bottom).offset(10);
        make.height.equalTo(@40);
    }];
    
    [_genButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(_clearBtn.mas_right).mas_equalTo(50);
        make.right.mas_equalTo(-50);
        make.top.equalTo(containerView.mas_bottom).offset(10);
        make.height.equalTo(@40);
        make.width.equalTo(_clearBtn.mas_width);
    }];
}

/// 清除
- (void)clearAction {
    
    self.seed = 0;
    [self.boardView clear];
    [self.imagesArray removeAllObjects];
}

/// 绘图变化
- (void)drawPathChangeAction {
    
    self.seed ++;
    
    if (self.seed < 5 ||self.seed % 2 == 0) {
        
        UIImage *image = [_boardView capture];
        if (image) {
            [self.imagesArray addObject:image];
        }
        
        NSLog(@"__image count:%d",(int)self.imagesArray.count);
    }
}

/// image => PixelBuffer
- (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image {
    
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                             nil];

    CVPixelBufferRef pxbuffer = NULL;

    CGFloat frameWidth = CGImageGetWidth(image);
    CGFloat frameHeight = CGImageGetHeight(image);

    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,frameWidth,frameHeight,kCVPixelFormatType_32ARGB,(__bridge CFDictionaryRef) options, &pxbuffer);

    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);

    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
    NSParameterAssert(pxdata != NULL);

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, frameWidth, frameHeight, 8,CVPixelBufferGetBytesPerRow(pxbuffer),rgbColorSpace,(CGBitmapInfo)kCGImageAlphaNoneSkipFirst);

    NSParameterAssert(context);
    CGContextConcatCTM(context, CGAffineTransformIdentity);
    CGContextDrawImage(context, CGRectMake(0, 0,frameWidth,frameHeight),  image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}

/// 生成视频并播放
- (void)genVideoAction {
    
    if (self.imagesArray.count == 0) {
        return;
    }
    
    [self.view makeToastActivity:CSToastPositionCenter];
    
    __weak typeof(self) weakSelf = self;
    NSLog(@"___start record :%@",[NSDate date]);
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf startRecord:VideoPath];
        [weakSelf.view hideToastActivity];
        NSLog(@"___end record :%@",[NSDate date]);
    });
}

/// 生成视频
/// @param moviePath 视频路径
- (void)startRecord:(NSString *)moviePath {
    
    if([[NSFileManager defaultManager] fileExistsAtPath:moviePath]) {
        [[NSFileManager defaultManager] removeItemAtPath:moviePath error:nil];
    }
    
    CGSize size = _boardView.bounds.size;
    NSError *error = nil;
    
    unlink([moviePath UTF8String]);
    AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:moviePath]
                                                           fileType:AVFileTypeQuickTimeMovie
                                                              error:&error];
    NSParameterAssert(videoWriter);
    if(error)
        NSLog(@"error = %@", [error localizedDescription]);
    
    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,
                                   [NSNumber numberWithInt:size.width], AVVideoWidthKey,
                                   [NSNumber numberWithInt:size.height], AVVideoHeightKey, nil];
    AVAssetWriterInput *writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
    NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];
    
    AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
                                                     assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];
    NSParameterAssert(writerInput);
    NSParameterAssert([videoWriter canAddInput:writerInput]);
    
    if ([videoWriter canAddInput:writerInput])
        NSLog(@"start");
    
    [videoWriter addInput:writerInput];
    
    [videoWriter startWriting];
    [videoWriter startSessionAtSourceTime:kCMTimeZero];
    
    dispatch_queue_t dispatchQueue = dispatch_queue_create("record", NULL);
    int __block frame = 0;
    
    __block NSMutableArray *imageArray = [_imagesArray mutableCopy];
    __block int total = (int)imageArray.count;
    
    __weak typeof(self) weakSelf = self;
    
    [writerInput requestMediaDataWhenReadyOnQueue:dispatchQueue usingBlock:^{
        
        CVPixelBufferRef buffer = NULL;
        
        while ([writerInput isReadyForMoreMediaData]) {
            
            if ([imageArray count] == 0) {
                
                [writerInput markAsFinished];
                
                [videoWriter finishWritingWithCompletionHandler:^{
                    
                    ////存入相册，模拟器调试在模拟器文件夹能看到视频，真机调试在相册能找到存入的视频。
                    //UISaveVideoAtPathToSavedPhotosAlbum (moviePath,nil,nil, nil);
                    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        
                        //播放
                        [weakSelf playVideoWhenRecordDoneAction];
                        
                        //保存到相册
                        //[weakSelf saveVideoToAlbumAction];
                    });
                    
                }];
                
                if (buffer) {
                    CFRelease(buffer);
                    buffer = NULL;
                }
                
                break;
            
            } else {
                
                if (buffer==NULL)  {
                    buffer = [self pixelBufferFromCGImage:[[imageArray objectAtIndex:0] CGImage]];
                }
                
                if (buffer) {
                    
                    CFAbsoluteTime interval = (total - [imageArray count]) * 50.0;//帧与帧的时间间隔
                    CMTime currentSampleTime = CMTimeMake((int)interval, 1000);
                    
                    if([adaptor appendPixelBuffer:buffer withPresentationTime:currentSampleTime]) {
                    
                        ++frame;
                        [imageArray removeObjectAtIndex:0];
                        CFRelease(buffer);
                        buffer = NULL;
                    }
                }
            }
        }
    }];
}

/// 播放视频
- (void)playVideoWhenRecordDoneAction {
    
    NSURL *url = [NSURL fileURLWithPath:VideoPath];

    AVPlayerViewController *ctrl = [[AVPlayerViewController alloc] init];
    ctrl.player= [[AVPlayer alloc]initWithURL:url];
    ctrl.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:ctrl animated:YES completion:nil];
}


/// 保存到相册
- (void)saveVideoToAlbumAction {
    
    //UISaveVideoAtPathToSavedPhotosAlbum(VideoPath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
    
    PHAssetCollection *desCollection;
    PHFetchResult <PHAssetCollection*>*result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    for (PHAssetCollection *collect in result) {
        desCollection = collect;
        NSLog(@"%@",collect.localizedTitle);
    }
    
    __block NSString *colID = nil;
    NSError *error = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        colID = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"video"].placeholderForCreatedAssetCollection.localIdentifier;
    } error:&error];
    if (error) {
        NSLog(@"创建相册: %@ 失败",colID);
    }
    NSLog(@"相册: %@ ",colID);
    
    __block PHObjectPlaceholder *placeholderAsset=nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        
        PHAssetChangeRequest*changeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:VideoPath]];
        placeholderAsset = changeRequest.placeholderForCreatedAsset;
    
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
    
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            
            PHAsset *asset = [[PHAsset fetchAssetsWithLocalIdentifiers:@[placeholderAsset.localIdentifier] options:nil] lastObject];
            
            [[PHAssetCollectionChangeRequest changeRequestForAssetCollection:desCollection] addAssets:@[asset]];
            
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            
            if (success) {
                NSLog(@"存入相册成功");
            }
        }];
    }];
    
}

@end
